home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / opengl / xlib / tesstest.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  21.7 KB  |  789 lines

  1. /*
  2.  * Copyright 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <GL/glx.h>
  18. #include <GL/glu.h>
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <unistd.h>
  22. #include <stdlib.h>
  23. #include <X11/keysym.h>
  24. #include <malloc.h>
  25. #include <assert.h>
  26.  
  27. static int RGB_SB_attributes[] = {
  28.     GLX_RGBA,
  29.     GLX_RED_SIZE, 1,
  30.     GLX_GREEN_SIZE, 1,
  31.     GLX_BLUE_SIZE, 1,
  32.     None,
  33. };
  34.  
  35. static int RGB_DB_attributes[] = {
  36.     GLX_RGBA,
  37.     GLX_RED_SIZE, 1,
  38.     GLX_GREEN_SIZE, 1,
  39.     GLX_BLUE_SIZE, 1,
  40.     GLX_DOUBLEBUFFER,
  41.     GLX_DEPTH_SIZE, 1,
  42.     GLX_STENCIL_SIZE, 1,
  43.     None,
  44. };
  45.  
  46. static int CI_SB_attributes[] = {
  47.     GLX_DEPTH_SIZE, 1,
  48.     GLX_STENCIL_SIZE, 1,
  49.     None,
  50. };
  51.  
  52. static int CI_DB_attributes[] = {
  53.     GLX_DOUBLEBUFFER,
  54.     GLX_DEPTH_SIZE, 1,
  55.     GLX_STENCIL_SIZE, 1,
  56.     None,
  57. };
  58.  
  59. int rgb = 1;
  60. int W = 500;
  61. int H = 500;
  62.  
  63. /*
  64. ** A contour.
  65. */
  66. struct vert {
  67.     GLdouble v[3];
  68.     struct vert *next;
  69. };
  70.  
  71. /*
  72. ** A polygon (multiple contours).
  73. */
  74. struct polygon {
  75.     struct vert *contour;
  76.     struct polygon *next;
  77. };
  78.  
  79. #define SELECT_LINE    1
  80. #define SELECT_VERTEX    2
  81.  
  82. struct polygon *thePoly = NULL;
  83. struct vert *foundVertex = NULL;
  84. int leftDown, middleDown, rightDown;
  85. int tessIt;
  86. int showTess;
  87. int doEdgeFlags;
  88. int gotError;
  89. int doubleBuf = 1;
  90. GLUtriangulatorObj *tobj;
  91. Display *dpy;
  92. Window window;
  93. Colormap cmap;
  94.  
  95. unsigned char font6x10[] = {
  96. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  97. 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x38, 0x38, 0x10, 0x00, 
  98. 0x00, 0x00, 0x54, 0x28, 0x54, 0x28, 0x54, 0x28, 0x54, 0x00, 
  99. 0x08, 0x08, 0x08, 0x3c, 0x48, 0x48, 0x78, 0x48, 0x48, 0x00, 
  100. 0x10, 0x10, 0x18, 0x10, 0x5c, 0x40, 0x60, 0x40, 0x70, 0x00, 
  101. 0x24, 0x24, 0x38, 0x24, 0x38, 0x38, 0x40, 0x40, 0x38, 0x00, 
  102. 0x20, 0x20, 0x38, 0x20, 0x3c, 0x78, 0x40, 0x40, 0x40, 0x00, 
  103. 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x28, 0x28, 0x38, 0x00, 
  104. 0x00, 0x00, 0x7c, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00, 
  105. 0x3c, 0x20, 0x20, 0x20, 0x48, 0x58, 0x68, 0x68, 0x48, 0x00, 
  106. 0x08, 0x08, 0x08, 0x08, 0x3c, 0x20, 0x30, 0x48, 0x48, 0x00, 
  107. 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x10, 0x10, 0x10, 0x10, 
  108. 0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x00, 0x00, 0x00, 0x00, 
  109. 0x10, 0x10, 0x10, 0x10, 0x10, 0x1c, 0x00, 0x00, 0x00, 0x00, 
  110. 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x10, 0x10, 0x10, 
  111. 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 
  112. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 
  113. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 
  114. 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 
  115. 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  116. 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  117. 0x10, 0x10, 0x10, 0x10, 0x10, 0x1c, 0x10, 0x10, 0x10, 0x10, 
  118. 0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x10, 0x10, 0x10, 0x10, 
  119. 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x10, 0x10, 0x10, 0x10, 
  120. 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x00, 
  121. 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
  122. 0x00, 0x7c, 0x04, 0x08, 0x20, 0x40, 0x20, 0x08, 0x04, 0x00, 
  123. 0x00, 0x7c, 0x40, 0x20, 0x08, 0x04, 0x08, 0x20, 0x40, 0x00, 
  124. 0x00, 0x00, 0x28, 0x28, 0x28, 0x28, 0x7c, 0x00, 0x00, 0x00, 
  125. 0x00, 0x00, 0x40, 0x20, 0x7c, 0x10, 0x7c, 0x08, 0x04, 0x00, 
  126. 0x00, 0x20, 0x6c, 0x38, 0x20, 0x78, 0x20, 0x24, 0x18, 0x00, 
  127. 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 
  128. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  129. 0x00, 0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 
  130. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28, 0x28, 0x00, 
  131. 0x00, 0x00, 0x28, 0x28, 0x7c, 0x28, 0x7c, 0x28, 0x28, 0x00, 
  132. 0x00, 0x00, 0x10, 0x38, 0x14, 0x38, 0x50, 0x38, 0x10, 0x00, 
  133. 0x00, 0x00, 0x48, 0x54, 0x28, 0x10, 0x28, 0x54, 0x24, 0x00, 
  134. 0x00, 0x00, 0x34, 0x48, 0x54, 0x20, 0x50, 0x50, 0x20, 0x00, 
  135. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x18, 0x00, 
  136. 0x00, 0x00, 0x08, 0x10, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, 
  137. 0x00, 0x00, 0x20, 0x10, 0x08, 0x08, 0x08, 0x10, 0x20, 0x00, 
  138. 0x00, 0x00, 0x00, 0x44, 0x28, 0x7c, 0x28, 0x44, 0x00, 0x00, 
  139. 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00, 
  140. 0x00, 0x20, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  141. 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 
  142. 0x00, 0x10, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  143. 0x00, 0x00, 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x04, 0x00, 
  144. 0x00, 0x00, 0x10, 0x28, 0x44, 0x44, 0x44, 0x28, 0x10, 0x00, 
  145. 0x00, 0x00, 0x7c, 0x10, 0x10, 0x10, 0x50, 0x30, 0x10, 0x00, 
  146. 0x00, 0x00, 0x7c, 0x40, 0x20, 0x18, 0x04, 0x44, 0x38, 0x00, 
  147. 0x00, 0x00, 0x38, 0x44, 0x04, 0x18, 0x08, 0x04, 0x7c, 0x00, 
  148. 0x00, 0x00, 0x08, 0x08, 0x7c, 0x48, 0x28, 0x18, 0x08, 0x00, 
  149. 0x00, 0x00, 0x38, 0x44, 0x04, 0x64, 0x58, 0x40, 0x7c, 0x00, 
  150. 0x00, 0x00, 0x38, 0x44, 0x64, 0x58, 0x40, 0x20, 0x18, 0x00, 
  151. 0x00, 0x00, 0x20, 0x20, 0x10, 0x08, 0x08, 0x04, 0x7c, 0x00, 
  152. 0x00, 0x00, 0x38, 0x44, 0x44, 0x38, 0x44, 0x44, 0x38, 0x00, 
  153. 0x00, 0x00, 0x30, 0x08, 0x04, 0x34, 0x4c, 0x44, 0x38, 0x00, 
  154. 0x00, 0x10, 0x38, 0x10, 0x00, 0x10, 0x38, 0x10, 0x00, 0x00, 
  155. 0x00, 0x20, 0x10, 0x18, 0x00, 0x10, 0x38, 0x10, 0x00, 0x00, 
  156. 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 
  157. 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x00, 0x00, 
  158. 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x10, 0x20, 0x40, 0x00, 
  159. 0x00, 0x00, 0x10, 0x00, 0x10, 0x10, 0x08, 0x44, 0x38, 0x00, 
  160. 0x00, 0x00, 0x38, 0x40, 0x58, 0x54, 0x4c, 0x44, 0x38, 0x00, 
  161. 0x00, 0x00, 0x44, 0x44, 0x7c, 0x44, 0x44, 0x28, 0x10, 0x00, 
  162. 0x00, 0x00, 0x78, 0x24, 0x24, 0x38, 0x24, 0x24, 0x78, 0x00, 
  163. 0x00, 0x00, 0x38, 0x44, 0x40, 0x40, 0x40, 0x44, 0x38, 0x00, 
  164. 0x00, 0x00, 0x78, 0x24, 0x24, 0x24, 0x24, 0x24, 0x78, 0x00, 
  165. 0x00, 0x00, 0x7c, 0x40, 0x40, 0x78, 0x40, 0x40, 0x7c, 0x00, 
  166. 0x00, 0x00, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x7c, 0x00, 
  167. 0x00, 0x00, 0x38, 0x44, 0x4c, 0x40, 0x40, 0x44, 0x38, 0x00, 
  168. 0x00, 0x00, 0x44, 0x44, 0x44, 0x7c, 0x44, 0x44, 0x44, 0x00, 
  169. 0x00, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 
  170. 0x00, 0x00, 0x38, 0x44, 0x04, 0x04, 0x04, 0x04, 0x1c, 0x00, 
  171. 0x00, 0x00, 0x44, 0x48, 0x50, 0x60, 0x50, 0x48, 0x44, 0x00, 
  172. 0x00, 0x00, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 
  173. 0x00, 0x00, 0x44, 0x44, 0x44, 0x54, 0x6c, 0x44, 0x44, 0x00, 
  174. 0x00, 0x00, 0x44, 0x44, 0x4c, 0x54, 0x64, 0x44, 0x44, 0x00, 
  175. 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 
  176. 0x00, 0x00, 0x40, 0x40, 0x40, 0x78, 0x44, 0x44, 0x78, 0x00, 
  177. 0x00, 0x04, 0x38, 0x54, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 
  178. 0x00, 0x00, 0x44, 0x48, 0x50, 0x78, 0x44, 0x44, 0x78, 0x00, 
  179. 0x00, 0x00, 0x38, 0x44, 0x04, 0x38, 0x40, 0x44, 0x38, 0x00, 
  180. 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 
  181. 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00, 
  182. 0x00, 0x00, 0x10, 0x28, 0x28, 0x28, 0x44, 0x44, 0x44, 0x00, 
  183. 0x00, 0x00, 0x44, 0x6c, 0x54, 0x54, 0x44, 0x44, 0x44, 0x00, 
  184. 0x00, 0x00, 0x44, 0x44, 0x28, 0x10, 0x28, 0x44, 0x44, 0x00, 
  185. 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x28, 0x44, 0x44, 0x00, 
  186. 0x00, 0x00, 0x7c, 0x40, 0x20, 0x10, 0x08, 0x04, 0x7c, 0x00, 
  187. 0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x38, 0x00, 
  188. 0x00, 0x00, 0x04, 0x04, 0x08, 0x10, 0x20, 0x40, 0x40, 0x00, 
  189. 0x00, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 
  190. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x28, 0x10, 0x00, 
  191. 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  192. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x30, 0x00, 
  193. 0x00, 0x00, 0x3c, 0x44, 0x3c, 0x04, 0x38, 0x00, 0x00, 0x00, 
  194. 0x00, 0x00, 0x58, 0x64, 0x44, 0x64, 0x58, 0x40, 0x40, 0x00, 
  195. 0x00, 0x00, 0x38, 0x44, 0x40, 0x44, 0x38, 0x00, 0x00, 0x00, 
  196. 0x00, 0x00, 0x34, 0x4c, 0x44, 0x4c, 0x34, 0x04, 0x04, 0x00, 
  197. 0x00, 0x00, 0x38, 0x40, 0x7c, 0x44, 0x38, 0x00, 0x00, 0x00, 
  198. 0x00, 0x00, 0x20, 0x20, 0x20, 0x78, 0x20, 0x24, 0x18, 0x00, 
  199. 0x38, 0x44, 0x38, 0x40, 0x30, 0x48, 0x34, 0x00, 0x00, 0x00, 
  200. 0x00, 0x00, 0x44, 0x44, 0x44, 0x64, 0x58, 0x40, 0x40, 0x00, 
  201. 0x00, 0x00, 0x38, 0x10, 0x10, 0x10, 0x30, 0x00, 0x10, 0x00, 
  202. 0x30, 0x48, 0x48, 0x08, 0x08, 0x08, 0x18, 0x00, 0x08, 0x00, 
  203. 0x00, 0x00, 0x44, 0x48, 0x70, 0x48, 0x44, 0x40, 0x40, 0x00, 
  204. 0x00, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 
  205. 0x00, 0x00, 0x44, 0x54, 0x54, 0x54, 0x68, 0x00, 0x00, 0x00, 
  206. 0x00, 0x00, 0x44, 0x44, 0x44, 0x64, 0x58, 0x00, 0x00, 0x00, 
  207. 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 
  208. 0x40, 0x40, 0x40, 0x58, 0x64, 0x64, 0x58, 0x00, 0x00, 0x00, 
  209. 0x04, 0x04, 0x04, 0x34, 0x4c, 0x4c, 0x34, 0x00, 0x00, 0x00, 
  210. 0x00, 0x00, 0x40, 0x40, 0x40, 0x64, 0x58, 0x00, 0x00, 0x00, 
  211. 0x00, 0x00, 0x78, 0x04, 0x38, 0x40, 0x38, 0x00, 0x00, 0x00, 
  212. 0x00, 0x00, 0x18, 0x24, 0x20, 0x20, 0x78, 0x20, 0x20, 0x00, 
  213. 0x00, 0x00, 0x34, 0x4c, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 
  214. 0x00, 0x00, 0x10, 0x28, 0x28, 0x44, 0x44, 0x00, 0x00, 0x00, 
  215. 0x00, 0x00, 0x28, 0x54, 0x54, 0x44, 0x44, 0x00, 0x00, 0x00, 
  216. 0x00, 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 
  217. 0x38, 0x44, 0x04, 0x34, 0x4c, 0x44, 0x44, 0x00, 0x00, 0x00, 
  218. 0x00, 0x00, 0x7c, 0x20, 0x10, 0x08, 0x7c, 0x00, 0x00, 0x00, 
  219. 0x00, 0x00, 0x0c, 0x10, 0x08, 0x30, 0x08, 0x10, 0x0c, 0x00, 
  220. 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 
  221. 0x00, 0x00, 0x60, 0x10, 0x20, 0x18, 0x20, 0x10, 0x60, 0x00, 
  222. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x54, 0x24, 0x00, 
  223. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  224. };
  225.  
  226. int fontbase;
  227.  
  228. void initializeFont(void)
  229. {
  230.     int i;
  231.  
  232.     fontbase=glGenLists(256);
  233.     glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
  234.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  235.  
  236.     for (i=0; i<128; i++) {
  237.     glNewList(i+fontbase, GL_COMPILE);
  238.     glBitmap(6, 10, 0.0, 0.0, 6.0, 0.0, font6x10+10*i);
  239.     glEndList();
  240.     }
  241. }
  242.  
  243. void writeFont(char *string)
  244. {
  245.     glListBase(fontbase);
  246.     glCallLists(strlen(string), GL_BYTE, (unsigned char *) string);
  247. }
  248.  
  249. void myBegin(GLenum which)
  250. {
  251.     glBegin(which);
  252. }
  253.  
  254. void myEnd(void)
  255. {
  256.     glEnd();
  257. }
  258.  
  259. void tessPoly(void)
  260. {
  261.     struct polygon *poly;
  262.     struct vert *vert;
  263.  
  264.     gluBeginPolygon(tobj);
  265.     for (poly=thePoly; poly; poly=poly->next) {
  266.     gluNextContour(tobj, GLU_UNKNOWN);
  267.     for (vert=poly->contour; vert; vert=vert->next) {
  268.         gluTessVertex(tobj, vert->v, vert->v);
  269.     }
  270.     }
  271.     gluEndPolygon(tobj);
  272. }
  273.  
  274. static void Redraw(GLenum mode)
  275. {
  276.     struct polygon *poly;
  277.     struct vert *vert;
  278.  
  279.     glClear(GL_COLOR_BUFFER_BIT);
  280.     glPointSize(3);
  281.  
  282.     gotError = 0;
  283.     glInitNames();
  284.     if (tessIt) {
  285.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  286.     glColor3f(0.5, 0.5, 0.5);
  287.     glIndexf(15);
  288.     tessPoly();
  289.     }
  290.     if (!gotError && showTess) {
  291.     glColor3f(1.0, 1.0, 0.0);
  292.     glIndexf(3);
  293.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  294.     tessPoly();
  295.     }
  296.     if (!gotError && doEdgeFlags) {
  297.     glLineWidth(3);
  298.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  299.     glColor3f(0.0, 0.0, 1.0);
  300.     glIndexf(4);
  301.     gluTessCallback(tobj, GLU_EDGE_FLAG, (void *) glEdgeFlag);
  302.     tessPoly();
  303.     gluTessCallback(tobj, GLU_EDGE_FLAG, NULL);
  304.     glLineWidth(1);
  305.     }
  306.  
  307.     if (gotError) {
  308.     glColor3f(1.0, 1.0, 1.0);
  309.     glIndexf(7);
  310.     glRasterPos2f(5.0, 15.0);
  311.     glColor3f(0.0, 0.0, 1.0);
  312.     glIndexf(4);
  313.     writeFont((char *) gluErrorString(gotError));
  314.     }
  315.  
  316.     /* So glLoadName will be legal -- strange semantics */
  317.     glPushName(1);
  318.     for (poly=thePoly; poly; poly=poly->next) {
  319.     glColor3f(0.0, 1.0, 0.0);
  320.     glIndexf(2);
  321.     glLoadName(SELECT_LINE);
  322.     for (vert=poly->contour; vert; vert=vert->next) {
  323.         glPushName((GLuint) vert);
  324.         glBegin(GL_LINES);
  325.         glVertex2dv(vert->v);
  326.         if (vert->next) {
  327.         glVertex2dv(vert->next->v);
  328.         } else {
  329.         glVertex2dv(poly->contour->v);
  330.         }
  331.         glEnd();
  332.         glPopName();
  333.     }
  334.     glColor3f(1.0, 0.0, 0.0);
  335.     glIndexf(1);
  336.     glLoadName(SELECT_VERTEX);
  337.     for (vert=poly->contour; vert; vert=vert->next) {
  338.         glPushName((GLuint) vert);
  339.         glBegin(GL_POINTS);
  340.         glVertex2dv(vert->v);
  341.         glEnd();
  342.         glPopName();
  343.     }
  344.     }
  345.  
  346.     if (mode == GL_RENDER) {
  347.     glXSwapBuffers(dpy, window);
  348.     }
  349. }
  350.  
  351. static void Usage(void)
  352. {
  353.     fprintf(stderr, "Usage: tesstest [-c] [-s]\n");
  354.     fprintf(stderr, " -c:  run in color index mode\n");
  355.     fprintf(stderr, " -s:  run in singlebuffer mode\n");
  356.     exit(1);
  357. }
  358.  
  359. static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
  360. {
  361.     if ((e->type == MapNotify) && (e->xmap.window == (Window) arg)) {
  362.     return GL_TRUE;
  363.     }
  364.     return GL_FALSE;
  365. }
  366.  
  367. /*
  368. ** Create a new contour at x,y.
  369. */
  370. void newContour(int x, int y)
  371. {
  372.     struct polygon *newPoly;
  373.     struct vert *newCont;
  374.     struct polygon **polyTail;
  375.  
  376.     newPoly = (struct polygon *) malloc(sizeof(struct polygon));
  377.     newCont = (struct vert *) malloc(sizeof(struct vert));
  378.  
  379.     polyTail = &thePoly;
  380.     while (*polyTail) {
  381.     polyTail = &((*polyTail)->next);
  382.     }
  383.  
  384.     *polyTail = newPoly;
  385.     newPoly->next = NULL;
  386.     newPoly->contour = newCont;
  387.  
  388.     newCont->next = NULL;
  389.     newCont->v[0] = x;
  390.     newCont->v[1] = y;
  391.     newCont->v[2] = 0;
  392. }
  393.  
  394. /*
  395. ** Create a new edge at this vertex
  396. */
  397. struct vert *addVertex(struct vert *where, int x, int y)
  398. {
  399.     struct vert *newVert;
  400.  
  401.     newVert = (struct vert *) malloc(sizeof(struct vert));
  402.  
  403.     newVert->next = where->next;
  404.     where->next = newVert;
  405.     newVert->v[0] = x;
  406.     newVert->v[1] = y;
  407.     newVert->v[2] = 0;
  408.  
  409.     return newVert;
  410. }
  411.  
  412. void deleteVertex(void)
  413. {
  414.     struct polygon *poly, *poly2;
  415.     struct vert *vert;
  416.  
  417.     if (!foundVertex) return;
  418.  
  419.     for (poly=thePoly; poly; poly=poly->next) {
  420.     if (poly->contour == foundVertex) {
  421.         poly->contour = foundVertex->next;
  422.         free(foundVertex);
  423.         foundVertex = NULL;
  424.         if (poly->contour == NULL) {
  425.         if (poly == thePoly) {
  426.             thePoly = poly->next;
  427.             free(poly);
  428.             return;
  429.         }
  430.         for (poly2=thePoly; poly2; poly2=poly2->next) {
  431.             if (poly2->next == poly) {
  432.             poly2->next = poly->next;
  433.             free(poly);
  434.             return;
  435.             }
  436.         }
  437.         }
  438.         return;
  439.     }
  440.     for (vert=poly->contour; vert; vert=vert->next) {
  441.         if (vert->next == foundVertex) {
  442.         vert->next = foundVertex->next;
  443.         free(foundVertex);
  444.         foundVertex = NULL;
  445.         return;
  446.         }
  447.     }
  448.     }
  449. }
  450.  
  451. void findVertex(int x, int y, int type)
  452. {
  453.     static GLuint selectBuf[1000];
  454.     GLint hits;
  455.     GLint viewport[4];
  456.     int i;
  457.  
  458.     foundVertex = NULL;
  459.     glSelectBuffer(1000, selectBuf);
  460.     (void) glRenderMode(GL_SELECT);
  461.     glInitNames();
  462.  
  463.     glMatrixMode(GL_PROJECTION);
  464.     glPushMatrix();
  465.     glLoadIdentity();
  466.     glGetIntegerv(GL_VIEWPORT, viewport);
  467.     gluPickMatrix(x, y, 6, 6, viewport);
  468.     gluOrtho2D(0,W,0,H);
  469.     glMatrixMode(GL_MODELVIEW);
  470.  
  471.     Redraw(GL_SELECT);
  472.  
  473.     glMatrixMode(GL_PROJECTION);
  474.     glPopMatrix();
  475.  
  476.     hits = glRenderMode(GL_RENDER);
  477.     if (hits <= 0) return;
  478.  
  479.     /*
  480.     ** Each entry looks like:
  481.     **   count (2)
  482.     **   min z, max z
  483.     **   SELECT_LINE or SELECT_VERTEX
  484.     **   pointer to vertex.
  485.     */
  486.  
  487.     i = 0;
  488.     while (hits) {
  489.     hits --;
  490.     if (selectBuf[i] == 0) {
  491.         i+= 3;
  492.         continue;
  493.     }
  494.     assert(selectBuf[i] == 2);
  495.     i += 3;
  496.     if (selectBuf[i] == type) {
  497.         foundVertex = (struct vert *) selectBuf[i+1];
  498.         return;
  499.     }
  500.     i += 2;
  501.     }
  502. }
  503.  
  504. void moveVertex(int x, int y)
  505. {
  506.     if (foundVertex) {
  507.     foundVertex->v[0] = x;
  508.     foundVertex->v[1] = y;
  509.     }
  510. }
  511.  
  512. void errorHandler(GLenum error)
  513. {
  514.     if (gotError) {
  515.     printf("Double errors!?!\n");
  516.     }
  517.     gotError = error;
  518. }
  519.  
  520. static void Init(void)
  521. {
  522.     glViewport(0,0,W,H);
  523.     glMatrixMode(GL_PROJECTION);
  524.     glLoadIdentity();
  525.     gluOrtho2D(0,W,0,H);
  526.     glMatrixMode(GL_MODELVIEW);
  527.  
  528.     if (rgb) {
  529.     glClearColor(0,0,0,0);
  530.     } else {
  531.     glClearIndex(0);
  532.     }
  533.  
  534.     glClear(GL_COLOR_BUFFER_BIT);
  535.  
  536.     tobj = gluNewTess();
  537.     gluTessCallback(tobj, GLU_VERTEX, glVertex2dv);
  538.     gluTessCallback(tobj, GLU_BEGIN, myBegin);
  539.     gluTessCallback(tobj, GLU_END, myEnd);
  540.     gluTessCallback(tobj, GLU_ERROR, errorHandler);
  541.  
  542.     initializeFont();
  543. }
  544.  
  545. static void setColorMap(void)
  546. {
  547.     XColor *xc;
  548.     long i;
  549.  
  550.     xc = (XColor *) malloc(16 * sizeof(XColor));
  551.     for (i=0; i<16; i++) {
  552.     xc[i].pixel = i;
  553.     xc[i].red = (i & 1) ? 65535 : 0;
  554.     xc[i].green = (i & 2) ? 65535 : 0;
  555.     xc[i].blue = (i & 4) ? 65535 : 0;
  556.     if (i > 8) {
  557.         xc[i].red /= 2;
  558.         xc[i].green /= 2;
  559.         xc[i].blue /= 2;
  560.     }
  561.     xc[i].flags = DoRed | DoGreen | DoBlue;
  562.     }
  563.     XStoreColors(dpy, cmap, xc, 16);
  564.  
  565.     free((void *) xc);
  566. }
  567.  
  568. int main(int argc, char** argv)
  569. {
  570.     XVisualInfo *vi;
  571.     XSetWindowAttributes swa;
  572.     GLXContext cx;
  573.     XEvent event;
  574.     GLboolean needDisplay;
  575.     XColor white;
  576.     int i;
  577.  
  578.     rgb = 1;
  579.     for (i = 1; i < argc; i++) {
  580.         if (argv[i][0] == '-') {
  581.             switch (argv[i][1]) {
  582.               case 'c':
  583.                 rgb = GL_FALSE;
  584.                 break;
  585.           case 's':
  586.         doubleBuf = 0;
  587.         break;
  588.               default:
  589.                 Usage();
  590.             }
  591.         } else {
  592.             Usage();
  593.         }
  594.     }
  595.  
  596.     dpy = XOpenDisplay(0);
  597.     if (!dpy) {
  598.     fprintf(stderr, "Can't connect to display \"%s\"\n", getenv("DISPLAY"));
  599.     return -1;
  600.     }
  601.  
  602.     vi = glXChooseVisual(dpy, DefaultScreen(dpy),
  603.         doubleBuf ? (rgb ? RGB_DB_attributes : CI_DB_attributes) :
  604.         (rgb ? RGB_SB_attributes : CI_SB_attributes));
  605.     if (!vi) {
  606.     fprintf(stderr, "No singlebuffered rgba visual on \"%s\"\n",
  607.         getenv("DISPLAY"));
  608.     return -1;
  609.     }
  610.  
  611.     cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
  612.                rgb ? AllocNone : AllocAll);
  613.     white.red = ~0;
  614.     white.green = ~0;
  615.     white.blue = ~0;
  616.     XAllocColor(dpy, cmap, &white);
  617.  
  618.     swa.border_pixel = 0;
  619.     swa.background_pixel = white.pixel;
  620.     swa.colormap = cmap;
  621.     swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask
  622.     | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
  623.     PointerMotionMask;
  624.     window = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 10, 10,
  625.                W, H,
  626.                0, vi->depth, InputOutput, vi->visual,
  627.                CWBackPixel|CWBorderPixel|CWColormap|CWEventMask,
  628.                &swa);
  629.     XSetWMColormapWindows(dpy, window, &window, 1);
  630.     XMapWindow(dpy, window);
  631.     XIfEvent(dpy, &event, WaitForMapNotify, (char*)window);
  632.  
  633.     cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
  634.     if (!glXMakeCurrent(dpy, window, cx)) {
  635.     fprintf(stderr, "Can't make window current to context\n");
  636.     return -1;
  637.     }
  638.  
  639.     if (!rgb) {
  640.     setColorMap();
  641.     }
  642.  
  643.     Init();
  644.  
  645.     printf("\n\nc to create a new contour.\n");
  646.     printf("d to delete a vertex.\n");
  647.     printf("t to tessellate and draw the polygon.\n");
  648.     printf("s to show the tessellation.\n");
  649.     printf("e to draw the polygon in Polymode(GL_LINE) with edge flags.\n");
  650.     printf("Left mouse moves a vertex.\n");
  651.     printf("Middle mouse inserts a vertex into a contour.\n");
  652.  
  653.     needDisplay = GL_TRUE;
  654.     leftDown = middleDown = rightDown = GL_FALSE;
  655.     newContour(100, 100);
  656.     findVertex(100, 100, SELECT_VERTEX);
  657.     addVertex(foundVertex, 100, 400);
  658.     findVertex(100, 400, SELECT_VERTEX);
  659.     addVertex(foundVertex, 400, 400);
  660.     findVertex(400, 400, SELECT_VERTEX);
  661.     addVertex(foundVertex, 400, 100);
  662.     foundVertex = NULL;
  663.     for (;;) {
  664.     do {
  665.         GLboolean setNeed;
  666.  
  667.         XNextEvent(dpy, &event);
  668.         setNeed = GL_TRUE;
  669.         switch (event.type) {
  670.           case Expose:
  671.         break;
  672.           case ConfigureNotify:
  673.         W = event.xconfigure.width;
  674.         H = event.xconfigure.height;
  675.         glViewport(0,0,W,H);
  676.         glMatrixMode(GL_PROJECTION);
  677.         glLoadIdentity();
  678.         gluOrtho2D(0,W,0,H);
  679.         glMatrixMode(GL_MODELVIEW);
  680.         break;
  681.           case ButtonPress:
  682.         /* 
  683.         ** Only effectively allow one mouse button down at a time.
  684.         */
  685.         setNeed = GL_FALSE;
  686.         leftDown = middleDown = rightDown = GL_FALSE;
  687.         switch(event.xbutton.button) {
  688.           case 1:    /* Left - move vertex */
  689.             findVertex(event.xbutton.x, H - event.xbutton.y, 
  690.                 SELECT_VERTEX);
  691.             moveVertex(event.xbutton.x, H - event.xbutton.y);
  692.             leftDown = GL_TRUE;
  693.             break;
  694.           case 2:    /* Middle - insert vertex */
  695.             middleDown = GL_TRUE;
  696.             findVertex(event.xbutton.x, H - event.xbutton.y, 
  697.                 SELECT_LINE);
  698.             if (foundVertex) {
  699.             foundVertex = addVertex(foundVertex, 
  700.                 event.xbutton.x, H - event.xbutton.y);
  701.             }
  702.             break;
  703.           case 3:    /* Right */
  704.             rightDown = GL_TRUE;
  705.             break;
  706.         }
  707.         break;
  708.           case ButtonRelease:
  709.         setNeed = GL_FALSE;
  710.         switch(event.xbutton.button) {
  711.           case 1:
  712.             if (leftDown && foundVertex) {
  713.             moveVertex(event.xbutton.x, H - event.xbutton.y);
  714.             leftDown = GL_FALSE;
  715.             setNeed = GL_TRUE;
  716.             } 
  717.             break;
  718.           case 2:
  719.             if (middleDown && foundVertex) {
  720.             moveVertex(event.xbutton.x, H - event.xbutton.y);
  721.             middleDown = GL_FALSE;
  722.             setNeed = GL_TRUE;
  723.             }
  724.             break;
  725.           case 3:
  726.             rightDown = GL_FALSE;
  727.             break;
  728.         }
  729.         break;
  730.           case MotionNotify:
  731.         if (leftDown && foundVertex) {
  732.             moveVertex(event.xmotion.x, H - event.xmotion.y);
  733.         } else if (middleDown && foundVertex) {
  734.             moveVertex(event.xmotion.x, H - event.xmotion.y);
  735.         } else {
  736.             setNeed = GL_FALSE;
  737.         }
  738.         break;
  739.           case KeyPress:
  740.         {
  741.             char buf[100];
  742.             int rv;
  743.             KeySym ks;
  744.  
  745.             rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
  746.             switch (ks) {
  747.               case XK_C: case XK_c:
  748.             newContour(event.xkey.x, H - event.xkey.y);
  749.             break;
  750.               case XK_D: case XK_d:
  751.             findVertex(event.xbutton.x, H - event.xbutton.y, 
  752.                 SELECT_VERTEX);
  753.             if (foundVertex) {
  754.                 deleteVertex();
  755.             } else setNeed = GL_FALSE;
  756.             break;
  757.               case XK_T: case XK_t:
  758.             tessIt = 1-tessIt;
  759.             break;
  760.               case XK_S: case XK_s:
  761.             showTess = 1-showTess;
  762.             break;
  763.               case XK_E: case XK_e:
  764.             doEdgeFlags = 1-doEdgeFlags;
  765.             break;
  766.               case XK_Escape:
  767.             return 0;
  768.               default:
  769.             setNeed = GL_FALSE;
  770.             break;
  771.             }
  772.         }
  773.         break;
  774.           default:
  775.         setNeed = GL_FALSE;
  776.         break;
  777.         }
  778.         if (setNeed) needDisplay = GL_TRUE;
  779.     } while (XPending(dpy) != 0);
  780.  
  781.     if (needDisplay) {
  782.         needDisplay = GL_FALSE;
  783.         Redraw(GL_RENDER);
  784.     }
  785.     }
  786. }
  787.  
  788.  
  789.